#!/usr/bin/env python
# coding:utf-8
from PoboAPI import *
import datetime
import numpy as np
from math import ceil

def OnStart(context) :
    print("I\'m starting...")
    g.product = 'rb'
    g.exchange = GetExchangeByVariety(g.product)
    g.code = GetMainContract(g.exchange, g.product,20)    #以当月主力合约为标的
    g.cL = 16    #截断阀值
    g.sL = 2        #偏移周期数
    g.period = 0        #开盘以来的周期数量
    g.position = 0    #持仓量
    g.close_price = 0        #离场价位
    g.AF = 0        #加速因子
    g.ini_af = 0.035
    g.max_af = 0.2 #加速因子上限
    g.diff_af = 0.02 #加速率
    g.position_rate = 0.2 #仓位比例
    print(('初始主力：%s ' %g.code))
    SubscribeBar(g.code, BarType.Min5)
    context.myacc = None
    g.position_flag = 0
    if "回测期货" in context.accounts :
        print("登录交易账号[回测期货]")
        if context.accounts["回测期货"].Login() :
            context.myacc = context.accounts["回测期货"]
    g.alarm_id =  SetAlarm(datetime.time(14, 59), RepeatType.Daily)
    g.alarm_id2 =  SetAlarm(datetime.time(22, 59), RepeatType.Daily)
    g.initial_flag = -1
    
#闹钟事件
def OnAlarm(context, alarmid):
        if g.initial_flag == -1:
            return
        #每日收盘前平仓
        option = PBObj()
        option.contract = g.code
        pos = context.myacc.GetPositions(option)
        price_type=PriceType(PbPriceType.Limit,16)
        for p in pos:
            if p.bstype.BuySellFlag=="0":
                QuickInsertOrder(context.myacc,g.code,'sell','close',price_type,p.volume)
            if p.bstype.BuySellFlag=="1":
                QuickInsertOrder(context.myacc,g.code,'buy','close',price_type,p.volume)
        g.position_flag = 0
        g.initial_flag = -1
    
def OnMarketQuotationInitialEx(context, exchange,daynight):
        if exchange!=g.exchange:
            return
        #如果当月合约改变，以新的合约为标的
        if GetMainContract(g.exchange, g.product,20)!=g.code:
            UnsubscribeBar(g.code, BarType.Min5)
            print(("主力变更，由%s变为%s" %(g.code,GetMainContract(g.exchange, g.product,20))))
            g.code = GetMainContract(g.exchange, g.product,20)
            SubscribeBar(g.code,BarType.Min5)
        print(('当日主力：%s ' %g.code))
        g.initial_flag = 0
        g.period = 0
        g.position_flag = 0
        g.open_market_time = GetCurrentTime()
        g.close_price = 0        #离场价位
        g.AF = 0        #加速因子

def OnBar(context,code,bartype):
        if g.initial_flag < 0 :
            return
        g.period += 1
        if g.period <=g.cL:
            return
        df = GetHisDataByFieldAsDF(g.code, ['high', 'low','close','datetime'], bar_type=BarType.Min5, start_date=g.open_market_time)
        if len(df) < g.cL:
            return
        print((df.iloc[-3:]))
        mH = np.max(df.iloc[:-1-g.sL].loc[:,'high'])
        sL = np.min(df.iloc[:-1-g.sL].loc[:,'low'])
        now_price = df.iloc[-2]['close']
        print((mH,sL,now_price,g.close_price,g.AF))
        aPrice = PriceType(PbPriceType.Limit,16,0)
        if now_price > mH:
            print(("当前价格：%f 向上突破：%f" %(now_price,mH)))
            if g.position_flag == 0:
                print("多头开仓")
#                 volume = 1
                context.myacc.RefreshMargin(g.code, BSType.BuyOpen)
                print("当前价格%f，手数%d" %(now_price,context.myacc.GetValidVolume(g.code, BSType.BuyOpen,now_price)))
                print(context.myacc.GetMargin(code,BSType.BuyOpen).Rate)
                volume = int(ceil(g.position_rate*context.myacc.GetValidVolume(g.code, BSType.BuyOpen,now_price)))
                QuickInsertOrder(context.myacc,code,'buy','open',aPrice,volume)
                g.position_flag = 1
                g.position = volume
#                 g.close_price = df.iloc[-2]['low']
                g.close_price = np.min(df.iloc[-5:-2]['low'])
                g.AF = g.ini_af
                return
            if g.position_flag == 1:
                print("加速")
                g.AF +=g.diff_af
                g.AF = min(g.AF,g.max_af)
        elif now_price < sL:                
            print(("当前价格：%f 向下突破：%f" %(now_price,sL)))
            if g.position_flag == 0:
                print("空头开仓")
#                 volume = 1
                volume = int(ceil(g.position_rate*context.myacc.GetValidVolume(g.code, BSType.SellOpen,now_price)))
                QuickInsertOrder(context.myacc,code,'sell','open',aPrice,volume)
                g.position = volume
                g.position_flag = -1
#                 g.close_price = df.iloc[-2]['high']
                g.close_price = np.max(df.iloc[-5:-2]['high'])
                g.AF = g.ini_af
                return
            if g.position_flag == -1:
                print("加速")
                g.AF += g.diff_af
                g.AF = min(g.AF,g.max_af)
        print(("posi",g.position_flag))
        if g.position_flag == 1:
            if now_price <= g.close_price:
                QuickInsertOrder(context.myacc,code,'sell','close',aPrice,g.position)
                g.position = 0
                g.position_flag = 0
                g.AF = 0
                g.close_price = 0
            else:
                max_h = np.max(df.loc[:,'high'])
                g.close_price = g.close_price + (max_h - g.close_price) * g.AF
        if g.position_flag == -1:
            if now_price >= g.close_price:
                QuickInsertOrder(context.myacc,code,'buy','close',aPrice,g.position)
                g.position = 0
                g.position_flag = 0
                g.AF = 0
                g.close_price = 0
            else:
                min_l = np.min(df.loc[:,'low'])
                print((g.close_price,min_l))
                g.close_price = g.close_price - (g.close_price-min_l) * g.AF